package com.lagou.demo.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.io.StringReader;
import java.util.Properties;

/**
 * @Description zookeeper客户端连接
 * @Author 郭汝诚
 * @Date 2020/7/26 13:07
 * @Version 1.0
 **/
@Component
public class ZkClient {

    @Value("${dataSourcePath}")
    private String dataSourcePath;

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public CuratorFramework curatorFramework() throws Exception {
        //创建zk客户端连接
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("192.168.3.110:2181")
                .sessionTimeoutMs(50000)
                .connectionTimeoutMs(30000)
                .retryPolicy(retryPolicy)
                .build();
        client.start();

        // 判断根节点是否存在，不存在创建节点
        Stat exists = client.checkExists().forPath(dataSourcePath);
        if(exists == null){
            String context = "url=jdbc:mysql://localhost:3306/task3.2.1?serverTimezone=UTC&characterEncoding=utf-8\n" +
                    "username=root\n" +
                    "password=root\n" +
                    "driver-class-name=com.mysql.cj.jdbc.Driver";
            client.create().withMode(CreateMode.PERSISTENT).forPath(dataSourcePath,context.getBytes());
        }

        //对数据源配置节点信息注册监听
        NodeCache cache = new NodeCache(client,dataSourcePath,false);
        NodeCacheListener listener = new NodeCacheListener() {
            //当节点信息发生变化时，触发节点变化通知
            @Override
            public void nodeChanged() throws Exception {
                ChildData currentData = cache.getCurrentData();

                //读取最新配置信息
                String context = new String(currentData.getData());
                Properties properties = new Properties();
                properties.load(new StringReader(context));

                DruidDataSource druidDataSource = (DruidDataSource) SpringUtil.getBean("dataSource");
                druidDataSource.restart();
                druidDataSource.setUrl(properties.getProperty("url"));
                druidDataSource.setUsername(properties.getProperty("username"));
                druidDataSource.setPassword(properties.getProperty("password"));
                druidDataSource.setDriverClassName(properties.getProperty("driver-class-name"));
            }
        };
        //启动监听
        cache.getListenable().addListener(listener);
        cache.start(true);
        return client;
    }

}
